package com.instpower.things.instpower;

import com.instpower.things.transport.DataBuffer;
import com.instpower.things.transport.Response;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @ClassName Connection
 * @Author: hellmash@gmail.com
 * @Date: 2020/3/1
 * @Version: 1.0.0
 * @Description: 连接封装类
 */
public class Connection {
    protected final static Logger logger = LoggerFactory.getLogger("CORE");
    private String mId;
    private volatile boolean isClosed = false;
    private ChannelHandlerContext mContext;
    private ConnectionCloseListener closeListener;

    public Connection(String id, ChannelHandlerContext ctx) {
        mId = id;
        mContext = ctx;
    }

    public String getId() {
        return mId;
    }

    public ChannelHandlerContext getmContext() {
        return mContext;
    }


    public boolean isActive() {
        return mContext != null && mContext.channel().isActive();
    }

    public boolean isClosed() {
        return isClosed || !isActive();
    }

    public void close() {
        if (!isClosed) {
            mContext.channel().close();
            notifyRemoved();
        }
    }

    /**
     * 向终端发送报文
     * @param resp
     */
    public void sendResponse(DataBuffer resp) {
        this.sendResponse(resp, Boolean.TRUE);
    }

    /**
     * //TODO
     * @param resp
     * @param needCheck
     */
    public void sendResponse(DataBuffer resp, boolean needCheck){
        if (isActive()) {
            mContext.writeAndFlush(resp);
        }else{
            //TODO 不在线的手表需要放入到缓存中做二次处理
        }
    }

    /**
     * 发送多个请求
     * @param resps
     */
    public void sendResponse(Response... resps) {
        if (isActive()) {
            this.mContext.channel().eventLoop().execute(() -> {
                try {
                    for (int i = 0; i < resps.length; i++) {
                        if(mContext!=null && resps[i]!=null) {
                            mContext.writeAndFlush(resps[i]);
                        }else{
                            logger.debug("context is {} , response is {}",mContext,resps[i]);
                        }
                    }
                } catch (Exception e) {
                    logger.error(e.getLocalizedMessage(),e);
                }
            });
        }
    }

    /**
     * 关闭当前连接
     */
    public void notifyRemoved() {
        if (closeListener != null) {
            closeListener.onClosed(this);
        }
        isClosed = true;
        mContext = null;
        closeListener = null;
    }


    public void registerCloseListener(ConnectionCloseListener listener) {
        if (closeListener != null) {
            throw new IllegalStateException("Close listener already configured");
        }
        if (isClosed()) {
            listener.onClosed(this);
        } else {
            closeListener = listener;
        }
    }

    public void removeCloseListener(ConnectionCloseListener listener) {
        if (closeListener == listener) {
            closeListener = null;
        }
    }

    public interface ConnectionCloseListener {
        public void onClosed(Connection connection);
    }

    private static final class DefaultFutureListener implements ChannelFutureListener {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            future.isDone();
        }
    }
}
